package com.ayz.gateway.server.grpc.connection;

import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;

import com.ayz.gateway.server.grpc.GrpcServerConstants;
import io.grpc.Attributes;
import io.grpc.Grpc;
import io.grpc.ServerTransportFilter;
import lombok.Data;

import java.net.InetSocketAddress;

/**
 * @ClassName AddressTransportFilter
 * @Description TODO: 服务端连接的过滤器
 * 在与客户端连接通道建立的过程中 在通道建立read 或者 通道销毁时 完成ConnectionManger的维护
 * @Author 快乐的星球
 * @Date 2023/5/19 18:36
 * @Version 1.0
 **/
@Data
public class AddressTransportFilter extends ServerTransportFilter {

    private final Log LOG=Log.get(AddressTransportFilter.class);

    /**
     * 连接管理器
     */
    private ConnectionManger connectionManger;
    public AddressTransportFilter(ConnectionManger connectionManger) {
        this.connectionManger = connectionManger;
    }
    /**
     * 在通道第一次创建并且处于Ready状态时调用
     * @param transportAttrs 通道的属性
     * @return
     */
    @Override
    public Attributes transportReady(Attributes transportAttrs) {
        //客户端地址
        InetSocketAddress clientAddress =(InetSocketAddress) transportAttrs.get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR);
        //服务器地址
        InetSocketAddress localAddress =(InetSocketAddress) transportAttrs.get(Grpc.TRANSPORT_ATTR_LOCAL_ADDR);
        assert clientAddress != null;
        //客户端的IP地址
        String clientIp=clientAddress.getHostString();
        //客户端的端口号
        int clientPort=clientAddress.getPort();

        assert localAddress != null;
        int listenPort=localAddress.getPort();
        //当前传输通道的Key值
        String connectionKey=ConnectionManger.generateConnectionKey(clientIp,clientPort);
        /**
         * TODO: 维护好ConnectionManger
         *
         */
        ConnectionManger.Connection connection=new ConnectionManger.Connection(clientIp,clientPort,ConnectionManger.generateAddress(clientIp,clientPort));
        getConnectionManger().registryConnection(connectionKey,connection);
        return transportAttrs.toBuilder().set(GrpcServerConstants.ATTR_TRANS_KEY_CONN_ID,connectionKey)
                .set(GrpcServerConstants.ATTR_TRANS_KEY_REMOTE_IP,clientIp)
                .set(GrpcServerConstants.ATTR_TRANS_KEY_REMOTE_PORT,clientPort)
                .set(GrpcServerConstants.ATTR_TRANS_KEY_LOCAL_PORT,listenPort).build();
    }

    /**
     * 当与客户端的传输通道断开的时候会调用当前方法
     * 完成善后工作
     * @param transportAttrs
     */
    @Override
    public void transportTerminated(Attributes transportAttrs) {
        String connectionKey = transportAttrs.get(GrpcServerConstants.ATTR_TRANS_KEY_CONN_ID);
        if(StrUtil.isNotBlank(connectionKey)){
            LOG.info("与客户端的数据传输通道关闭;connectionKey:{"+connectionKey+"}");
            connectionManger.unRegistryConnection(connectionKey);
        }
    }
}
